package com.gitee.huanminabc.jcommon.multithreading;

import java.util.concurrent.locks.StampedLock;
import java.util.function.Supplier;

/**
 * StampedLock 简易封装，支持乐观读、悲观读、悲观写，适合高并发下的读多写少场景。
 * <p>
 * - 乐观读：性能高，但不保证强一致性，适合容忍短暂脏读的场景。
 * - 悲观读/写：保证强一致性。
 *
 * <b>典型用法：</b>
 * <pre>
 *   SimpleStampedLock lock = new SimpleStampedLock();
 *   // 乐观读
 *   String v = lock.optimisticRead(() -> data);
 *   // 悲观读
 *   String v2 = lock.read(() -> data);
 *   // 写
 *   lock.write(() -> { data = "new"; });
 * </pre>
 */
public class SimpleStampedLock {

    private final StampedLock lock = new StampedLock();

    /**
     * 乐观读（双重校验，保证一致性）
     */
    public <V1> V1 optimisticRead(Supplier<V1> consumer) {
        long stamp = lock.tryOptimisticRead();
        V1 value = consumer.get();
        if (!lock.validate(stamp)) {
            stamp = lock.readLock();
            try {
                value = consumer.get();
            } finally {
                lock.unlockRead(stamp);
            }
        }
        return value;
    }

    /**
     * 悲观读（强一致性）
     */
    public <V1> V1 read(Supplier<V1> consumer) {
        long stamp = lock.readLock();
        try {
            return consumer.get();
        } finally {
            lock.unlockRead(stamp);
        }
    }

    /**
     * 悲观读（无返回值）
     */
    public void read(Runnable runnable) {
        long stamp = lock.readLock();
        try {
            runnable.run();
        } finally {
            lock.unlockRead(stamp);
        }
    }

    /**
     * 悲观写（有返回值）
     */
    public <V1> V1 write(Supplier<V1> function) {
        long stamp = lock.writeLock();
        try {
            return function.get();
        } finally {
            lock.unlockWrite(stamp);
        }
    }

    /**
     * 悲观写（无返回值）
     */
    public void write(Runnable function) {
        long stamp = lock.writeLock();
        try {
            function.run();
        } finally {
            lock.unlockWrite(stamp);
        }
    }
}
